/*Compile with 
  gcc -std=99 -pthread threads_basic1.c -o threads_basic1*/


#include <pthread.h>
#include <stdio.h>

#define NUM_THREADS					10
#define NUM_ELEM_PER_THREAD	5
#define ARRAY_LENGTH        NUM_THREADS * NUM_ELEM_PER_THREAD

long array_long[ARRAY_LENGTH];

//prototype function PrintHello
void* PrintHello(void *threadid);


//function main
int main (int argc, char **argv)
{
   //declare variable i
   long i, t;
   int rc;
   //declare an array of threads
   pthread_t threads[NUM_THREADS];

   //initialize array elements with -1
   for(i = 0; i < ARRAY_LENGTH; i++){
       array_long[i] = -1;
   }

   //for loop 
   for(t = 0; t < NUM_THREADS; t++){
      //print message
      //printf("In main(): creating thread %lu\n", t);
      //create threads and each thread will call function PrintHello
      //an error is returned in variable rc if any occurs during thread creation 
      int rc = pthread_create(&threads[t], NULL, &PrintHello, (void *)t);

      //add error handling: show an error if an error is returned when creating a thread 
      if (rc){                          
         printf("Error creating thread %lu; Return code from pthread_create() is %d\n", t, rc);                            
      }     

	    //iterate over the array and print it's content
      //each thread will show only NUM_ELEM_PER_THREAD elements from the array ( the elements that it should update)
      for(i = t * NUM_ELEM_PER_THREAD; (i < (t+1) * NUM_ELEM_PER_THREAD) && (i < ARRAY_LENGTH); i++){
		    printf("thread=%lu index=%lu data: %lu\n", t, i, array_long[i]);
	    }
	    printf("\n");

   }

   /* Last thing that main() should do */
   pthread_exit(NULL);
}

//function PrintHello
void* PrintHello(void *threadid)
{
  //declare variables
  long i;
  long t = (long)threadid;

  //print message
  //printf("Hello World! It's me, thread #%lu!\n", t);

  //iterate over the array and set it's elements to have the value of the thread id
  //each thread will update only NUM_ELEM_PER_THREAD elements from the array
  for(i = t * NUM_ELEM_PER_THREAD; (i < (t+1) * NUM_ELEM_PER_THREAD) && (i < ARRAY_LENGTH); i++){
	  array_long[i] = t;
  }

  //exit thread
  pthread_exit(NULL);

  //return NULL
  return NULL;
}





